package com.deer.wms.project.root.util;



import com.deer.wms.project.root.annotaiton.MyAnnotation;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @Author: xu
 * @Date: 2022/01/15/9:20
 * @Description:
 */
public class Excel {


    /**
     * 输出excel文件
     *
     * @param data 数据集合
     */
    public static void outExcelFile(List<?> data, HttpServletResponse response, Class<?> tClass) {
        // 创建workbook
        XSSFWorkbook wb = new XSSFWorkbook();
        // 创建sheet
        Sheet sheet = wb.createSheet("sheel");
        // 创建表头行
        Row row = sheet.createRow(0);

        // 创建单元格样式
        XSSFCellStyle style = wb.createCellStyle();
        // 居中显示
        //style.setAlignment(HorizontalAlignment.CENTER);

        Field[] fields;
        if (ObjectUtils.isEmpty(data)) {
            // 获取实体所有属性
            fields = tClass.getDeclaredFields();
        } else {
            fields = data.get(0).getClass().getDeclaredFields();
        }
        // 列索引
        int index = 0;
        // 列名称
        String name = "";
        MyAnnotation myAnnotation;

        // 创建表头
        for (Field f : fields) {
            // 是否是注解
            if (f.isAnnotationPresent(MyAnnotation.class)) {
                // 获取注解
                myAnnotation = f.getAnnotation(MyAnnotation.class);
                // 获取列索引
                index = myAnnotation.columnIndex();
                // 列名称
                name = myAnnotation.columnName();
                // 创建单元格
                creCell(row, index, name, style);
            }
        }

        // 行索引  因为表头已经设置，索引行索引从1开始
        int rowIndex = 1;
        for (Object obj : data) {
            // 创建新行，索引加1,为创建下一行做准备
            row = sheet.createRow(rowIndex++);
            for (Field f : fields) {
                // 设置属性可访问
                f.setAccessible(true);
                // 判断是否是注解
                if (f.isAnnotationPresent(MyAnnotation.class)) {
                    // 获取注解
                    myAnnotation = f.getAnnotation(MyAnnotation.class);
                    // 获取列索引
                    index = myAnnotation.columnIndex();
                    try {
                        // 创建单元格     f.get(obj)从obj对象中获取值设置到单元格中
                        creCell(row, index, String.valueOf(f.get(obj)), style);
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            wb.write(os);
            String filename = UUID.randomUUID() + ".xlsx";

            new DownloadUtils().download(os, response, filename);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void outExcelTotal(List<?> data, HttpServletResponse response) {
        // 创建workbook
        XSSFWorkbook wb = new XSSFWorkbook();
        // 创建sheet
        Sheet sheet = wb.createSheet("sheel");
        // 创建表头行
        Row row = sheet.createRow(0);

        // 创建单元格样式
        XSSFCellStyle style = wb.createCellStyle();
        // 居中显示
        //style.setAlignment(HorizontalAlignment.CENTER);

        // 获取实体所有属性
        Field[] fields = data.get(0).getClass().getDeclaredFields();
        // 列索引
        int index = 0;
        // 列名称
        String name = "";
        MyAnnotation myAnnotation;

        // 创建表头
        for (Field f : fields) {
            // 是否是注解
            if (f.isAnnotationPresent(MyAnnotation.class)) {
                // 获取注解
                myAnnotation = f.getAnnotation(MyAnnotation.class);
                // 获取列索引
                index = myAnnotation.columnIndex();
                // 列名称
                name = myAnnotation.columnName();
                // 创建单元格
                creCell(row, index, name, style);
            }
        }


        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            wb.write(os);
            String filename = UUID.randomUUID() + ".xlsx";

            new DownloadUtils().download(os, response, filename);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 读取excel文件，并把读取到的数据封装到clazz中
     *
     * @param is       输入流
     * @param clazz    实体类
     * @param fileName 文件名
     * @return 返回clazz集合
     */
//    public static <T extends Object> List<T> readExcelFile(InputStream is, Class<T> clazz, String fileName) {
//
//        // 存储excel数据
//        List<T> list = new ArrayList<>();
//
//
//        Workbook wookbook = null;
//
//        // 根据excel文件版本获取工作簿
//        if (fileName.endsWith(".xls")) {
//            wookbook = xls(is);
//        } else if (fileName.endsWith(".xlsx")) {
//            wookbook = xlsx(is);
//        } else {
//            throw new RuntimeException("文件出错，非excel文件");
//        }
//
//        // 得到一个工作表
//        Sheet sheet = wookbook.getSheetAt(0);
//
//        // 获取行总数
//        int rows = sheet.getLastRowNum() + 1;
//
//        Row row;
//
//        // 获取类所有属性
//        Field[] fields = clazz.getDeclaredFields();
//
//        T obj = null;
//        int coumnIndex = 0;
//        Cell cell = null;
//        MyAnnotation myAnnotation = null;
//        for (int i = 1; i < rows; i++) {
//            // 获取excel行
//            row = sheet.getRow(i);
//            try {
//                // 创建实体
//                obj = clazz.newInstance();
//                for (Field f : fields) {
//                    // 设置属性可访问
//                    f.setAccessible(true);
//                    // 判断是否是注解
//                    if (f.isAnnotationPresent(MyAnnotation.class)) {
//                        // 获取注解
//                        myAnnotation = f.getAnnotation(MyAnnotation.class);
//                        // 获取列索引
//                        coumnIndex = myAnnotation.columnIndex();
//                        // 获取单元格
//                        if (ObjectUtils.isEmpty(row)) {
//                            continue;
//                        }
//                        cell = row.getCell(coumnIndex);
//                        // 设置属性
//                        if (ObjectUtils.isNotEmpty(cell)) {
//                            setFieldValue(obj, f, wookbook, cell);
//                        }
//                    }
//                }
//                // 添加到集合中
//                list.add(obj);
//            } catch (InstantiationException e1) {
//                e1.printStackTrace();
//            } catch (IllegalAccessException e1) {
//                e1.printStackTrace();
//            }
//
//        }
//        try {
//            is.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        return list;
//    }

    /**
     * 创建单元格
     *
     * @param row
     * @param c
     * @param cellValue
     * @param style
     */
    private static void creCell(Row row, int c, String cellValue, CellStyle style) {
        Cell cell = row.createCell(c);
        cell.setCellValue(cellValue);
        cell.setCellStyle(style);
    }

    /**
     * 设置属性值
     *
     * @param obj  操作对象
     * @param f    对象属性
     * @param cell excel单元格
     */
//    private static void setFieldValue(Object obj, Field f, Workbook wookbook, Cell cell) {
//        int cellType = cell.getCellType();
//        //16608701
//        String value = excleType(cell);
//        if (value.equals("1.6608701E7")) {
//            System.out.println("1111");
//        }
//
//        try {
//            if (ObjectUtils.isNotEmpty(value)) {
//                if (f.getType() == int.class || f.getType() == Integer.class) {
//
//                    f.set(obj, Integer.valueOf(value));
//                } else if (f.getType() == Double.class || f.getType() == double.class) {
//                    f.set(obj, Double.valueOf(value));
//                } else if (f.getType() == LocalDate.class) {
//                    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//                    f.set(obj, LocalDate.parse(value, df));
//                } else if (f.getType() == LocalDateTime.class) {
//                    DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//                    f.set(obj, LocalDate.parse(value, df));
//                } else if (f.getType() == Long.class) {
//                    f.set(obj, Long.valueOf(value));
//                } else {
//                    f.set(obj, value);
//                }
//            }
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//            //TODO  导入数据可能类型转换异常,
//        } catch (NumberFormatException e) {
//            e.printStackTrace();
//
//        }
//    }

//    /**
//     * 转换excle类型
//     *
//     * @param cell
//     * @return
//     */
//    public static String excleType(Cell cell) {
//
//
//        String value;
//        switch (cell.getCellType()) {
//            // 数字
//            case HSSFCell.CELL_TYPE_NUMERIC:
//                //如果为时间格式的内容
//                if (HSSFDateUtil.isCellDateFormatted(cell)) {
//                    //注：format格式 yyyy-MM-dd hh:mm:ss 中小时为12小时制，若要24小时制，则把小h变为H即可，yyyy-MM-dd HH:mm:ss
//                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//                    value = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())).toString();
//                    break;
//                } else {
//                    value = String.valueOf(cell.getNumericCellValue());
//                    String[] split = value.split("\\.");
//                    //整型不保留小数部分
//                    if (split[1].length() == 1 && split[1].equals("0")) {
//                        value = split[0];
//                        break;
//                    }
//                    break;
//                }
//                // 字符串
//            case HSSFCell.CELL_TYPE_STRING:
//                value = cell.getStringCellValue();
//                break;
//            // Boolean
//            case HSSFCell.CELL_TYPE_BOOLEAN:
//                value = cell.getBooleanCellValue() + "";
//                break;
//            // 公式
//            case HSSFCell.CELL_TYPE_FORMULA:
//                value = cell.getCellFormula() + "";
//                break;
//            // 空值
//            case HSSFCell.CELL_TYPE_BLANK:
//                value = "";
//                break;
//            // 故障
//            case HSSFCell.CELL_TYPE_ERROR:
//                value = "非法字符";
//                break;
//            default:
//                value = "未知类型";
//                break;
//        }
//
//        return value;
//    }

    /**
     * 对excel 2003处理
     */
    private static Workbook xls(InputStream is) {
        try {
            // 得到工作簿
            return new HSSFWorkbook(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 对excel 2007处理
     */
    private static Workbook xlsx(InputStream is) {
        try {
            // 得到工作簿
            return new XSSFWorkbook(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

//    public static Map<String, List<String>> returnExcelData(InputStream is, String fileName) throws IOException, IllegalAccessException, ParseException {
//
//
//        Workbook wookbook = null;
//
//        // 根据excel文件版本获取工作簿
//        if (fileName.endsWith(".xls")) {
//            wookbook = xls(is);
//        } else if (fileName.endsWith(".xlsx")) {
//            wookbook = xlsx(is);
//        } else {
//            throw new RuntimeException("文件出错，非excel文件");
//        }
//
//        int totalRows = 0;
//
//        /** 总列数 */
//
//         int totalCells = 0;
//
//            Map<String, List<String>> dataMap = new HashMap<String, List<String>>();
//
//            /** 得到第一个shell */
//
//            Sheet sheet = wookbook.getSheetAt(0);
//
//            /** 得到Excel的行数 */
//
//            totalRows = sheet.getPhysicalNumberOfRows();
//
//            /** 得到Excel的列数 */
//
//            if (totalRows >= 1 && sheet.getRow(0) != null) {
//                totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
//
//            }
//
//            for (int lie = 1; lie <= totalCells; lie++) {
//                List<String> list = new ArrayList<String>();
//                dataMap.put("第" + lie + "列", list);
//            }
//
//            /** 循环Excel的行 */
//
//            for (int r = 0; r < totalRows; r++) {
//
//                Row row = sheet.getRow(r);
//
//                if (row == null) {
//
//                    continue;
//
//                }
//                List<String> rowLst = new ArrayList<String>();
//
//                /** 循环Excel的列 */
//
//                for (int c = 0; c < totalCells; c++) {
//                    Cell cell = row.getCell(c);
//                    String cellValue = "";
//
//                    if (null != cell) {
//                        // 以下是判断数据的类型
//                        switch (cell.getCellType()) {
//                            case HSSFCell.CELL_TYPE_NUMERIC: // 数字
//                                cellValue = cell.getNumericCellValue() + "";
//                                break;
//
//                            case HSSFCell.CELL_TYPE_STRING: // 字符串
//                                cellValue = cell.getStringCellValue();
//                                break;
//
//                            case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
//                                cellValue = cell.getBooleanCellValue() + "";
//                                break;
//
//                            case HSSFCell.CELL_TYPE_FORMULA: // 公式
//                                cellValue = cell.getCellFormula() + "";
//                                break;
//
//                            case HSSFCell.CELL_TYPE_BLANK: // 空值
//                                cellValue = "";
//                                break;
//
//                            case HSSFCell.CELL_TYPE_ERROR: // 故障
//                                cellValue = "非法字符";
//                                break;
//
//                            default:
//                                cellValue = "未知类型";
//                                break;
//                        }
//                    }
//
//                    dataMap.get("第" + (c + 1) + "列").add(cellValue);
//
//                }
//
//            }
//            return dataMap;
//
//
//    }

}
